<?php

namespace sms;

use sms\common\StringUtil;
use sms\interfaces\SMSInterface;
use SMSBundle\Controller\SMSController;
use Symfony\Component\DependencyInjection\ContainerInterface;

abstract class AbstractSms extends SMSController implements SMSInterface
{
    protected static $conn = null;//数据库链接对象
    protected static $config = null;

    public function __construct(ContainerInterface $container = null)
    {
        parent::__construct($container);
        if(self::$config == null){
            self::$config = Config::getSDKConfig($container);
        }

        self::$conn = $this->get('database_connection');
    }

    /**
     * 发送短信验证码
     *
     * @param $phone
     * @param $sale
     * @param $type
     * @return mixed
     */
    abstract function userMessage($phone, $sale, $type);

    /**
     * 模板
     *
     * @param $phone
     * @param $sale
     * @param $type
     * @return mixed
     */
    abstract function template($phone, $sale, $type);

    /**
     * 重写返回值
     *
     * @param $result
     * @return mixed
     */
    abstract function returnRewrite($result);


    /**
     * 短信验证码验证
     *
     * @param $phone
     * @param $sale
     * @param $type
     * @return array|mixed
     */
    public function isSale($phone, $sale, $type)
    {
        $dataBaseTableName = self::$config->dataBaseTableName;
        $result = ['errorCode'=>1,'message'=>''];

        if(empty($sale)){
            $result['message'] = self::MSG_SALE_EMPTY_ERROR;
            return $result;
        }

        $saltInfo = self::$conn->fetchAssoc(
            "SELECT * FROM {$dataBaseTableName} WHERE phone = ? AND type = ? AND salt = ?  AND is_used = 0 LIMIT 1",
            [
                $phone,
                $type,
                $sale
            ]
        );
        //是否存在
        if(empty($saltInfo)){
            $result['message'] = self::MSG_SALE_ERROR;
            return $result;
        }

        //是否只可用一次
        if( self::$config->usedTime == 1 ){
            //需验证是否使用
            if ( $saltInfo['is_used'] == 1 ) {
                $result['message'] = self::MSG_SALE_USED_ERROR;
                return $result;
            }
        }else{
            //是否超出限制
            if ($saltInfo['times'] >= self::$config->usedTime) {
                $result['message'] = self::MSG_SALE_USED_OUT_ERROR;
                return $result;
            }
        }

        //是否过期
        if (time() - $saltInfo['happen_time'] > self::$config->expireTime) {
            $result['message'] = self::MSG_SALE_EXPIRE_ERROR;
            return $result;
        }

        //改为已使用
        if( $saltInfo['is_used'] == 0 ){
            self::$conn->update(
                $dataBaseTableName,
                ['is_used' => 1],
                ['id' => $saltInfo['id']]
            );
        }

        //验证次数加1
        self::$conn->update(
            $dataBaseTableName,
            ['times' => $saltInfo['times'] + 1],
            ['id' => $saltInfo['id']]
        );

        $result['errorCode'] = 0;
        return $result;
    }

    /**
     * 发送短信验证码
     *
     * @param $phone
     * @param $type
     * @return array|mixed
     * @throws \Doctrine\DBAL\DBALException
     */
    public function sendPhoneCode($phone, $type)
    {
        $dataBaseTableName = self::$config->dataBaseTableName;
        //注销以前的验证码
        self::$conn->executeUpdate(
            "UPDATE {$dataBaseTableName} SET happen_time = ? WHERE phone = ? and type = ? and happen_time >= ?",
            [
                time() - self::$config->expireTime,
                $phone,
                $type,
                time() - self::$config->expireTime
            ]
        );

        $stringUtil = new StringUtil();
        $data['salt'] = $stringUtil->generateRandom(self::$config->saltType,self::$config->saltNum);

        //发送短信验证码
        if(self::$config->trueSend == 1){
            $judge = $this->userMessage($phone, $data['salt'], $type);
            if($judge['errorCode'] != 0){
                return $judge;
            }
        }

        $data['phone'] = $phone;
        $data['happen_time'] = time();
        $data['times'] = 0;
        $data['is_used'] = 0;
        $data['ip'] = $_SERVER['REMOTE_ADDR'];
        $data['type'] = $type;
        self::$conn->insert($dataBaseTableName, $data);

        if(self::$config->isBeta == 0){
            $data['salt'] = null;
        }

        $result = array(
            'errorCode' => 0,
            'message' => self::MSG_SUCCESS,
            'data' => ['salt' => $data['salt']]
        );

        return $result;
    }
}
